﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Proggy.Data.Entities;

namespace Proggy.Data.Abstract
{
    /// <summary>
    /// The node repository interface
    /// </summary>
    public interface INodeRepository
    {
        /// <summary>
        /// The nodes
        /// </summary>
        //IQueryable<PublishableNode> PublishableNodes { get; }

        /// <summary>
        /// Draft nodes
        /// </summary>
        //IQueryable<DraftNode> DraftNodes { get; }

        /// <summary>
        /// Returns a single node from an id
        /// </summary>
        /// <param name="nodeId"></param>
        /// <returns></returns>
        PublishableNode GetPublishableNodeFromNodeId(int nodeId);

        /// <summary>
        /// Create a new node
        /// </summary>
        /// <param name="model"></param>
        /// <param name="errorString"></param>
        /// <param name="newNodeId"></param>
        /// <returns></returns>
        bool CreateNewNode(PublishableNode model, int? parentNodeId, ref string errorString, ref int newNodeId);

        /// <summary>
        /// Publish draft node
        /// </summary>
        /// <param name="node"></param>
        /// <param name="errorMsg"></param>
        /// <returns></returns>
        //bool PublishDraftNode(PublishableNode node, ref string errorMsg);

        /// <summary>
        /// Creates and returns a new draft node for a publishable node (based on publishable node's properties)
        /// </summary>
        /// <param name="publishable"></param>
        /// <returns></returns>
        DraftNode CreateAndGetDraftForPublished(PublishableNode publishable);

        /// <summary>
        /// Returns root node or null
        /// </summary>
        /// <returns></returns>
        PublishableNode GetRootNode();

        /// <summary>
        /// Save draft
        /// </summary>
        /// <param name="publishableNodeId"></param>
        /// <param name="jsonData"></param>
        /// <param name="errorMsg"></param>
        /// <returns></returns>
        bool SaveDraftNode(int publishableNodeId, string name, string urlSlug, string uniqueAlias, string Template, string jsonData, string currentUsername, ref string errorMsg);

        /// <summary>
        /// Publish draft to publishable and delete draft
        /// </summary>
        /// <param name="p"></param>
        /// <param name="data"></param>
        /// <param name="errorMsg"></param>
        /// <returns></returns>
        bool PublishDraftNode(int publishableNodeId, string name, string urlSlug, string uniqueAlias, string template, string jsonData, string currentUsername, ref string errorMsg);

        /// <summary>
        /// Disposes data context
        /// </summary>
        void DisposeDataContext();

        /// <summary>
        /// Revert to published version of node
        /// </summary>
        /// <param name="nodeId"></param>
        /// <param name="errorMsg"></param>
        /// <returns></returns>
        bool RevertToPublished(int nodeId, string errorMsg);

        /// <summary>
        /// Trash
        /// </summary>
        /// <param name="nodeId"></param>
        /// <param name="errorMsg"></param>
        /// <returns></returns>
        bool Trash(int nodeId, string currentUsername, ref string errorMsg);

        /// <summary>
        /// Trashed nodes
        /// </summary>
        IQueryable<TrashedNode> TrashedNodes { get; }

        /// <summary>
        /// Delete trashed content
        /// </summary>
        /// <param name="trashedNodeId"></param>
        /// <param name="errorMsg"></param>
        /// <returns></returns>
        bool DeleteTrashedContent(int trashedNodeId, ref string errorMsg);

        /// <summary>
        /// Get parent node id from child or null for home
        /// </summary>
        /// <param name="x"></param>
        /// <returns></returns>
        int? GetPublishableNodeParentId(int childId);

        /// <summary>
        /// Re orders child nodes of parent
        /// </summary>
        /// <param name="parentId"></param>
        /// <param name="orderedChildIds"></param>
        /// <param name="error"></param>
        /// <returns></returns>
        bool ReOrderChildren(int parentId, int[] orderedChildIds, ref string error);

        /// <summary>
        /// Move
        /// </summary>
        /// <param name="nodeToMoveId"></param>
        /// <param name="movingToNodeId"></param>
        /// <param name="errorMsg"></param>
        /// <returns></returns>
        bool Move(int nodeToMoveId, int movingToNodeId, ref string errorMsg);

        /// <summary>
        /// Restore
        /// </summary>
        /// <param name="model"></param>
        /// <param name="error"></param>
        /// <returns></returns>
        bool Restore(TrashedNode model, PublishableNode newPublishableNodeFromTrashed, ref string error, ref int newId);

        /// <summary>
        /// Check name ok
        /// </summary>
        /// <param name="node"></param>
        /// <param name="checkType"></param>
        /// <param name="error"></param>
        /// <returns></returns>
        bool NameIsOk(NodeBase node, NodeType checkType, ref string error);

        /// <summary>
        /// Check url ok
        /// </summary>
        /// <param name="node"></param>
        /// <param name="typeToCheck"></param>
        /// <param name="error"></param>
        /// <returns></returns>
        bool UrlIsOk(NodeBase node, NodeType typeToCheck, ref string error);

        /// <summary>
        /// Check alias ok
        /// </summary>
        /// <param name="node"></param>
        /// <param name="typeToCheck"></param>
        /// <param name="error"></param>
        /// <returns></returns>
        bool UniqueAliasIsUnique(NodeBase node, NodeType typeToCheck, ref string error);

        /// <summary>
        /// Get siblings from publishable node
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        IQueryable<PublishableNode> GetSiblingsForNode(PublishableNode node);

        /// <summary>
        /// Returns publishable nodes
        /// </summary>
        /// <param name="publishedOnly"></param>
        /// <returns></returns>
        IQueryable<PublishableNode> GetPublishableNodes(bool publishedOnly);
    }
}
